home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_0_m.arj
/
ATTPOINT.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-07-31
|
8KB
|
240 lines
; TURBO PASCAL CALLABLE
; AT&T 640*400 POINT SETTING ROUTINE
;
;Author: Rob Alexander
; 13217 Emily Lane
; Dallas,Tx 75240
; 214-644-9359
;
;Comments: I have heavily documented what I have learned about the
; AT&T 6300 640*400 graphics and handling the Turbo Pascal
; assembly language "interface"; parameter passing etc...
; I did this primarily as a reference for future work so
; I wouldn't have to fight the same battle twice. I hope
; others may benefit also.
;
;********************** STACK MEMORY MAP **************************
;
; PROCEDURE Point( X,Y:INTEGER;VAR Test: INTEGER) sets up the stack as
; follows
; < Top of Stack before Call > {Increasing addr}
; < X value (2 bytes)> {SP+8} {BP+10} ^
; < Y value (2 bytes)> {SP+6} {BP+8} *
; < Test value Segment addr (2 bytes)> *
; < Test value Offset addr (2 bytes)> {SP+2} {BP+4} *
; < Return Address (2 bytes)> {SP} {BP+2} *
; < BP register (2 bytes)> {SP-2} {BP} *
;
;*********************************************************************
;
; Define Point Procedure
;
; CONSTANTS DEFINITION
;
GraphSeg = 0B800H ;Graphics Memory Segment Address
;
CODE SEGMENT
Assume CS:Code
;
Point PROC NEAR
push bp ;Save Base pointer
mov bp,sp ;Initialize Base pointer
; les di,[bp+4] ;For test value passing
;****************** 8k BLOCK CALCULATION*****************************
;
;DISCUSSION: In 640 by 400 mode, the 32K graphics memory is divided into
; four 8000 byte long blocks. Each block contains the pixel
; definitions for 100 rows. According to the AT&T system programmers
; guide, the memory map looks like:
;
; ---------------- B800:7F3F
; * Rows *
; * 3,7,11..399 *
; ------------------ B800:6000
; ------------------ B800:5F3F
; * Rows *
; * 2,6,10,..398 *
; ------------------ B800:4000
; ------------------ B800:3F3F
; * Rows *
; * 1,5,9..397 *
; ------------------ B800:2000 {there are 192 unused bytes between
; ------------------ B800:1F3F blocks}
; * Rows *
; * 0,4,8,..396 *
; ------------------ B800:0000
;
;
; CALCULATION METHOD:
;
; 1) Read Y (row number) passed from Turbo Pascal
; 2) Determine remainder of Y/4. This is accomplished by masking upper 14
; bits of Y value so that
; LSB+1 LSB Action
; 0 0 Y value divisible by 4. Pixel in first 8 k block.
; 0 1 Remainder of 1/4. Pixel in second 8K block
; 1 0 Remainder of 1/2. Pixel in third 8K block
; 1 1 Remainder of 3/4. Pixel in fourth 8K block.
;
; 3) Multiply remainder by 2000H to obtain correct 8K page offset
;
; CONSTANTS DEFINITION
;
OffsetMult = 20H ;8K offset
Ymask = 03H ;Row number mask
OffsetShift = 08 ;shift count for result of offset calc.
;
; Algorithm: The offset calculation is done as
;
; a) ax<----8K_OffsetMult
; b) bx<----Row number
; c) bx<----Row number (AND) Ymask {Result is 8K_Block#}
; d) ax<----20H*Remainder {want result in AX register}
; e) ax<----20H*256 {Perform shift to obtain proper bit level
;
; Perform Calculation
;
mov ax,OffsetMult ;Offset multiplier
mov bx,[bp+8] ;Y value passed from Turbo
mov cl,OffsetShift ;Load CL register with shift count
and bl,Ymask ;mask off higher order bits
mul bl ;Find Bank offset
shl ax,cl ;Bring offset to correct bit level
mov dx,ax ;Save 8K_BlockOffset in DX
;
; ************************ Row Block Calculation ***********************
;
; Discussion: According to Systems Programmer guide, each 8K block contains
; the pixel values for 100 rows as follows;
;
; Row Number Offset
; /byte 0/byte 1/......./byte 79/ 99 8K_BlockOffset+99*80
; /byte 0/byte 1/......./byte 79/ 98 8K_BlockOffset+98*80
;
;
; /byte 0/byte 1/......./byte 79/ 1 8K_BlockOffset+1*80
; /byte 0/byte 1/......./byte 79/ 0 8K_Block#+0*80
;
; CALCULATION METHOD:
;
; 1) Read Y {row number} from stack
; 2) Row_Block# = Row Number/4
; 3) Row_Offset=Row_Block# * 80
; 4) Offset = 8K_Block Offset + Row_Offset
;
; ALGORITHM
; a) ax<---- Row_OffsetMult
; b) bx<---- Y value {Row number} passed from Turbo Pascal
; c) cl<---- Row_RmdrShift
; d) bx<---- Row number/4
; e) ax<---- (Row number/4)*80
; f) dx<---- 8K_BlockOffset + Row_BlockOffset
;
; CONSTANTS DEFINITION
;
Row_RmdrShift = 80
Row_BlockShift = 2
;
; Perform Calculation
;
mov al,Row_RmdrShift ;
mov bx,[BP+8] ;Read Y value passed from Turbo Pascal
mov cl,Row_BlockShift ;
shr bx,cl ;Divide Row number by 4
mul bl ;Find Row_Offset
add dx,ax ;Calculate offset
;
;*********************** COLUMN OFFSET CALCULATION ***********************
;
; Discussion: The pixel values for each row {640 pixels} are stored in
; 80 bytes. {1 bit per pixel} as shown below
; /byte 0/byte 1/......./byte n/...../byte 79/
; ^ ^
; |.. Row base address |..Column Address/8
;
; CALCULATION METHOD:
;
; 1) Column_byte_Addr=X value/8
;
; CONSTANTS DEFINITION
;
Column_Shift = 3
;
; PERFORM CALCULATION
;
mov ax,[bp+10] ;Read X value passed from Turbo Pascal
mov bx,ax ;Save X value for next calculation stage
mov cl,Column_Shift ;Initialize Shift count
shr ax,cl ;Divide X value by 8
add dx,ax ;Save Offset
;
;************************ PIXEL MASK GENERATION **************************
;
; Discussion: Finally, we're ready to set the pixel. The pixel bit map
; looks like
;
; /bit 7/ bit 6/......../bit 1/bit 0/
; pixel 0...^ ^..pixel 7
;
; {the bit map is the reverse from what you would expect}
;
; CALCULATION METHOD
;
; 1) Pixel No<----- Remainder{Column address,8}
; 2) Pixel Mask<---- 1 shifted by pixel number
; 3) Reg <---- Current Pixel Byte
; 4) Updated Pixel Byte<----Pixel Mask (OR) Pixel Settings
; 5) Mem<----- Pixel Byte
;
; CONSTANTS DEFINITION
;
Const= 128
Pixel_Rmdr_Mask = 0007
;
; PERFORM CALCULATION
;
mov ax,GraphSeg
mov es,ax
mov di,dx
and bl,Pixel_Rmdr_Mask ;Find remainder of Col#/8
mov cl,bl ;Generate Pixel Mask
mov bx,Const ;
shr bx,cl
mov al,byte ptr es:[di] ;Read Current Pixel Setting
or al,bl ;Set pixel
mov byte ptr es:[di],al
; mov word ptr es:[di],bx
;
; restore registers and return to Turbo
;
mov sp,bp
pop bp
;************************************************************************
;************************************************************************
;************************************************************************
;********* ATTENTION, ATTENTION, ATTENTION, ATTENTION *******************
;********* In order for External procedure to work, *******************
;********* you must figure out how many parameters *******************
;********* were passed on stack {in bytes} and *******************
;********* and include that number in return statemt. *******************
;********* In the case of this program; *******************
;********* *******************
;********* X co-ordinate value = 2 bytes *******************
;********* Y co-ordinate value = 2 bytes *******************
;********* Test value address = 4 bytes *******************
;********* ------- *******************
;********* 8 bytes *******************
;********* *******************
;********* It took me a hell of a long time to figure *******************
;********* that out.- Rob Alexander *******************
;************************************************************************
;************************************************************************
;************************************************************************
ret 08H ;Release Stack used for Call
Point ENDP
Code ENDS
END